home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
134_01
/
casm2.c
< prev
next >
Wrap
Text File
|
1985-08-19
|
24KB
|
945 lines
/*
CASM.C -- written by Leor Zolman, 2/82
Modified for v1.50 11/14/82
Modified for use with CTOA CRL-to-ASM postprocessor 11/2/83 K. Kenny
Modified to allow conditional assembly of relocatable code
11/15/83 K. Kenny.
CP/M ASM preprocessor: renders MAC.COM and CMAC.LIB unnecessary.
See the CASM Appendix in the User's Guide for complete information.
Compile and link with:
cc casm.c -o -e5000
l2 casm
(or) clink casm
*/
#include <bdscio.h>
#define TITLE "BD Software CRL-format ASM Preprocessor v1.50+mods\n"
/*
* Customizable definitions:
*/
#define DEFUSER "0/" /* default user area for include files */
/* make this a null string for "current" */
#define DEFDISK "A:" /* default disk for include files */
#define CASMEXT ".CSM" /* extension on input files */
#define ASMEXT ".ASM" /* extension on output files */
#define SUBFILE "A:$$$.SUB" /* Submit file to erase on error. To not */
/* erase any, use a null string ("") */
#define CONTROL_C 3 /* Abort character */
#define EQUMAX 500 /* maximum number of EQU ops */
#define FUNCMAX 100 /* maximum number of functions */
#define NFMAX 100 /* maximum number of external
functions in one function */
#define LABMAX 150 /* max number of local labels in one func */
#define TXTBUFSIZE 2000 /* max # of chars for labels and needed
function names for a single function */
#define CONDBUFSIZE 2000 /* max # of chars of conditional assembly
pseudo-ops per function */
/*
* End of customizable section
*/
#define DIRSIZE 512 /* max # of byte in CRL directory */
#define TPALOC 0x100 /* base of TPA in your system */
/* Global data used throughout processing
of the input file: */
char fbuf[BUFSIZ]; /* I/O buffer for main input file */
char incbuf[BUFSIZ]; /* I/O buffer for included file */
char obuf[BUFSIZ]; /* I/O buffer for output file */
char *cbufp; /* pointer to currently active input buf */
char *cfilnam; /* pointer to name of current input file */
char nambuf[30], /* filenames for current intput */
nambuf2[30], /* and output files. */
onambuf[30];
char *equtab[EQUMAX]; /* table of absolute symbols */
int equcount; /* # of entries in equtab */
char *fnames[FUNCMAX]; /* list of functions in the source file */
int fcount; /* # of entries in fnames */
int lino,savlino; /* line number values used for error */
/* reporting. */
char doingfunc; /* true if currently processing a function */
char errf; /* true if an error has been detected */
char verbose; /* true to insert wordy comments in output */
char careful; /* true to detect old CMAC.LIB macros */
char blankflag; /* true if last line processed was null */
/* Global data used during the processing of a
single function in the source file: */
char *nflist[NFMAX]; /* list of needed functions for a function */
int nfcount; /* number of entries in nflist */
struct {
char *labnam; /* name of function label */
char defined; /* whether it has been defined yet */
} lablist[LABMAX];
int labcount; /* number of local labels in a function */
char txtbuf[TXTBUFSIZE], /* where text of needed function names */
*txtbufp; /* and function labels go */
char condbuf[CONDBUFSIZE]; /* where conditional assembly directives go */
union {
int * ci;
char * cb;
} condptr;
char linbuf[150], /* text line buffers */
linsav[150],
workbuf[150],
undrbuf[150],
pbuf[150], *pbufp;
char *cfunam; /* pointer to name of current function */
int relblc; /* relocation object count for a function */
char pastnfs; /* true if we've passed all needed function */
/* declarations ("external" pseudo ops) */
int argcnt; /* values set by the "parse_line" function */
char *label,
*op,
*argsp,
*args[40];
char *gpcptr; /* general-purpose text pointer */
/*
* Open main input file, open output file, initialize needed globals
* and process the file:
*/
main(aarghc,aarghv)
char **aarghv;
{
int i,j,k;
char c, *inpnam, *outnam;
puts(TITLE);
initequ(); /* initialize EQU table with reserved words */
fcount = 0; /* haven't seen any functions yet */
doingfunc = FALSE; /* not currently processing a function */
errf = FALSE; /* no errors yet */
verbose = careful = FALSE;
inpnam = outnam = NULL; /* haven't seen any names yet */
blankflag = FALSE; /* haven't just processed a null line */
while (--aarghc)
{
++aarghv; /* bump to next arg text */
if (**aarghv == '-')
{
switch(c = aarghv[0][1])
{
case 'F':
careful = 1;
break;
case 'C':
verbose = 1;
break;
case 'O':
if (aarghv[0][2])
outnam = &aarghv[0][2];
else if (--aarghc)
outnam = *++aarghv;
else goto usage;
break;
default: goto usage;
}
}
else
inpnam = *aarghv;
}
if (!inpnam) {
usage: puts("Usage:\tcasm [-f] [-c] [-o <name>] <filename>\n");
puts("-F: flag old CMAC.LIB macros if spotted\n");
puts("-C: don't strip comments from input and output\n");
puts("-O <name>: Call the output file <name>.ASM\n");
exit();
}
/* set up filenames with proper extensions: */
for (i = 0; (c = inpnam[i]) && c != '.'; i++)
nambuf[i] = c;
nambuf[i] = '\0';
strcpy(onambuf, outnam ? outnam : nambuf);
strcat(nambuf,CASMEXT); /* input filename */
cbufp = fbuf; /* buffer pointer */
cfilnam = nambuf; /* current filename pointer */
if (fopen(cfilnam,cbufp) == ERROR)
exit(printf("Can't open %s\n",cfilnam));
if (!hasdot(onambuf))
strcat(onambuf,ASMEXT); /* output filename */
if (fcreat(onambuf,obuf) == ERROR)
exit(printf("Can't create %s\n",onambuf));
/* begin writing output file */
fprintf2(obuf,"\nTPALOC\t\tEQU\t%04xH\n",TPALOC);
fprintf2(obuf,"\nSYS$EXTFLAG\tSET\t0\n");
fprintf2(obuf,"SYS$EXTADDR\tSET\t0\n");
fprintf2(obuf,"SYS$EXTSIZE\tSET\t0\n");
fprintf2(obuf,"\t\tORG\tTPALOC+0205H\n\n");
lino = 1; /* initialize line count */
while (get_line()) { /* main loop */
if (kbhit() && getchar() == CONTROL_C)
abort("Aborted by ^C\n");
process_line(); /* process lines till EOF */
lino++;
}
if (doingfunc) /* if ends inside a function, error */
abort("File ends, but last function is unterminated\n");
if (errf)
{
puts("Fix those errors and try again...");
unlink(onambuf);
if (*SUBFILE)
unlink(SUBFILE);
}
else
{
/* end of functions */
fputs2("\nEND$CRL\t\tEQU\t$-TPALOC\n",obuf);
fputs2("SECTORS$ EQU ($-TPALOC)/256+1 ;USE FOR \"SAVE\" !.\n",
obuf);
putdir(); /* now put out CRL directory */
fputs2("\t\tEND\n",obuf); /* end of ASM file */
putc(CPMEOF,obuf); /* CP/M EOF character */
fclose(cbufp); /* close input file */
fclose(obuf); /* close output file */
printf("%s is ready to be assembled.\n",onambuf);
}
}
/*
* Get a line of text from input stream, and process
* "include" ops on the fly:
*/
int get_line()
{
int i;
top: if (!fgets(linbuf,cbufp)) { /* on EOF: */
if (cbufp == incbuf) { /* in an "include" file? */
fabort(cbufp->_fd); /* close the file */
cbufp = fbuf; /* go back to mainline file */
cfilnam = nambuf;
lino = savlino + 1;
return get_line();
}
else return NULL;
}
if (!verbose) /* strip commments, default */
{
for (i = 0; linbuf[i]; i++)
{
if (linbuf[i] == ';')
{
while (i && isspace(linbuf[i-1]))
i--;
if (!i && blankflag)
{
lino++;
goto top;
}
strcpy(&linbuf[i], "\n");
blankflag = TRUE;
break;
}
if (linbuf[i] == '\'' || linbuf[i] == '"')
break;
}
if (!linbuf[i])
blankflag = FALSE;
}
parse_line(); /* not EOF. Parse line */
if (streq(op,"INCLUDE") || /* check for file inclusion */
streq(op,"MACLIB")) {
if (cbufp == incbuf) /* if already in an include, */
abort("Only one level of inclusion is supported"); /* error */
if (!argsp)
abort("No filename specified");
cbufp =